<template>
  <div class="erp-bill-edit">
    <el-page-header @back="onBack" :content="isReadonly ? '单据详情' : '单据编辑'">
      <template #extra>
        <el-button size="small" @click="onViewFlow">查看流程</el-button>
      </template>
    </el-page-header>
    <el-card shadow="never" style="margin-top: 12px;">
      <el-form ref="formRef" :model="bill" label-width="96px">
        <el-row :gutter="12">
          <el-col :span="8">
            <el-form-item label="单据号">
              <el-input v-model="bill.billNo" :disabled="isEdit" :placeholder="isEdit ? '单据号' : '自动生成'" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item :label="partyLabel" prop="partyId">
              <el-select 
                v-model="bill.partyId" 
                filterable 
                remote 
                reserve-keyword 
                :remote-method="remoteParty" 
                :loading="loadingParty" 
                :disabled="bill.status === 'POSTED' || isReadonly"
                placeholder="输入编码/名称搜索"
              >
                <el-option v-for="p in partyOptions" :key="p.id" :label="p.label" :value="String(p.id)" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="仓库" prop="warehouseId">
              <el-select 
                v-model="bill.warehouseId" 
                filterable 
                remote 
                reserve-keyword 
                :remote-method="remoteWarehouse" 
                :loading="loadingWarehouse" 
                :disabled="bill.status === 'POSTED' || isReadonly"
                placeholder="输入编码/名称搜索"
              >
                <el-option v-for="w in warehouseOptions" :key="w.warehouseId" :label="`${w.warehouseCode} | ${w.warehouseName}`" :value="String(w.warehouseId)" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
      <el-form-item label="单价模式">
        <el-radio-group v-model="bill.priceMode" :disabled="bill.status === 'POSTED' || isReadonly">
          <el-radio label="TAX_INCLUDED">含税单价</el-radio>
          <el-radio label="TAX_EXCLUDED">未税单价</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item>
        <el-alert type="info" show-icon :closable="false" :title="priceModeHint" />
      </el-form-item>
      <el-form-item label="备注">
              <el-input v-model="bill.remark" :disabled="bill.status === 'POSTED' || isReadonly" />
            </el-form-item>
          </el-col>
      <el-col :span="24" v-if="bill.status">
        <el-alert :title="`当前状态：${bill.status}`" type="info" show-icon />
      </el-col>
        </el-row>
      </el-form>
    </el-card>

    <el-card shadow="never" style="margin-top: 12px;">
      <template #header>
        <div class="erp-bill-edit__header">
          <span>明细行</span>
          <div>
            <el-button 
              size="small" 
              type="primary" 
              :disabled="bill.status === 'POSTED' || isReadonly"
              @click="onAddLine"
            >
              新增行
            </el-button>
          </div>
        </div>
      </template>
      <el-table :data="items" size="small">
        <el-table-column label="#" type="index" width="60" />
        <el-table-column label="物料" min-width="220">
          <template #default="{ row }">
            <el-select 
              v-model="row.materialId" 
              filterable 
              remote 
              reserve-keyword 
              :remote-method="(q:string)=>remoteMaterial(q, row)" 
              :loading="loadingMaterial" 
              :disabled="bill.status === 'POSTED' || isReadonly"
              placeholder="输入编码/名称搜索"
            >
              <el-option v-for="m in materialOptions" :key="m.materialId" :label="`${m.materialCode} | ${m.materialName}`" :value="String(m.materialId)" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="计量单位" min-width="200">
          <template #default="{ row }">
            <el-select v-model="row.uomId" :disabled="bill.status === 'POSTED' || isReadonly" placeholder="选择单位">
              <el-option v-for="u in (row.uomOptions||[])" :key="u.uomId" :label="`${u.uomCode} | ${u.uomName}${u.base?'(基本)':''}${u.rate && !u.base ? ' ×'+u.rate : ''}`" :value="String(u.uomId)" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="数量" min-width="120">
          <template #default="{ row }">
            <el-input-number v-model="row.qty" :min="0" :precision="6" :disabled="bill.status === 'POSTED' || isReadonly" />
          </template>
        </el-table-column>
        <el-table-column label="单价" min-width="120">
          <template #default="{ row }">
            <el-input-number v-model="row.price" :min="0" :precision="6" :disabled="bill.status === 'POSTED' || isReadonly" />
          </template>
        </el-table-column>
        <el-table-column label="金额" min-width="120">
          <template #default="{ row }">{{ (Number(row.qty||0) * Number(row.price||0)).toFixed(6) }}</template>
        </el-table-column>
        <el-table-column label="税额" min-width="120">
          <template #default="{ row }">{{ calcLineTax(row).toFixed(6) }}</template>
        </el-table-column>
        <el-table-column label="单价来源" min-width="120">
          <template #default="{ row }">
            <el-tag :type="row.priceMatched ? 'success' : 'info'">{{ row.priceMatched ? '价目表' : '默认' }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="100">
          <template #default="{ $index }">
            <el-button 
              link 
              type="danger" 
              size="small" 
              :disabled="bill.status === 'POSTED' || isReadonly"
              @click="onRemoveLine($index)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <div class="erp-bill-edit__footer">
      <el-button @click="onBack">返回</el-button>
      <template v-if="!isReadonly">
        <el-button 
          v-if="bill.status !== 'POSTED'" 
          type="primary" 
          :loading="loading" 
          @click="onSave(false)"
        >
          保存
        </el-button>
        <el-button 
          v-if="bill.status !== 'POSTED'" 
          type="success" 
          :loading="loading" 
          @click="onSave(true)"
        >
          保存并提交
        </el-button>
        <el-alert 
          v-if="bill.status === 'POSTED'" 
          type="warning" 
          :closable="false" 
          style="margin-top: 12px;"
        >
          该单据已过账，无法编辑。如需修改，请先取消过账或创建新单据。
        </el-alert>
      </template>
      <el-alert 
        v-if="isReadonly" 
        type="info" 
        :closable="false" 
        style="margin-top: 12px;"
      >
        当前为只读模式，仅可查看单据信息。
      </el-alert>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, computed, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import type { FormInstance } from 'element-plus'
import { getBill, saveSubmit, listBillItems, getBillProcId, getNextBillNo } from '@/api/erp/bill'
import { pageMaterial } from '@/api/erp/material'
import { pageWarehouse } from '@/api/erp/warehouse'
import { listUomConv } from '@/api/erp/uom'
import { getDefaultPrice } from '@/api/erp/price'
import { ElMessage } from 'element-plus'
import { pageSupplier, pageCustomer } from '@/api/erp/party'

interface Props { id?: string; billType: 'PO_IN' | 'SO_OUT' }
const props = defineProps<Props>()

// 调试：检查 props
console.log('编辑页面初始化，props:', { id: props.id, billType: props.billType })

const router = useRouter()
const route = useRoute()
const formRef = ref<FormInstance>()
const loading = ref(false)

// 判断是否为只读模式（从路由query参数获取）
const isReadonly = computed(() => {
  // 只有明确传递 readonly='true' 时才为只读模式
  // 新建时不应该有 readonly 参数，所以不会是只读
  return route.query.readonly === 'true'
})

// 确保 billType 正确初始化
const initialBillType = props.billType || (router.currentRoute.value.path.includes('so-out') ? 'SO_OUT' : 'PO_IN')
console.log('初始化的 billType:', initialBillType)

const bill = reactive<any>({ 
  billId: undefined, 
  billNo: '', 
  billType: initialBillType, 
  partyId: '', 
  warehouseId: '', 
  remark: '', 
  status: 'DRAFT',
  priceMode: 'TAX_INCLUDED' // 默认含税模式
})
const items = reactive<any[]>([])
const materialOptions = ref<any[]>([])
const warehouseOptions = ref<any[]>([])
const loadingMaterial = ref(false)
const loadingWarehouse = ref(false)
const partyOptions = ref<any[]>([])
const loadingParty = ref(false)
const partyLabel = computed(() => bill.billType === 'PO_IN' ? '供应商' : '客户')

const isEdit = computed(() => !!props.id)
const priceModeHint = computed(() => {
  // 示例公式
  // 含税→未税：未税 = 含税 / (1 + 税率)
  // 未税→含税：含税 = 未税 * (1 + 税率)
  return bill.priceMode === 'TAX_INCLUDED'
    ? '当前显示含税单价。未税 = 含税 / (1 + 税率)；金额按数量×单价计算。'
    : '当前显示未税单价。含税 = 未税 × (1 + 税率)；金额按数量×单价计算。'
})

const load = async () => {
  if (!props.id) {
    // 新建时：生成单据号，确保 billType 正确
    // 强制使用 props.billType，如果为空则从路由判断
    const targetBillType = props.billType || (router.currentRoute.value.path.includes('so-out') ? 'SO_OUT' : 'PO_IN')
    bill.billType = targetBillType
    console.log('新建单据，props.billType:', props.billType, '目标billType:', targetBillType, 'bill.billType:', bill.billType)
    if (!bill.billNo && bill.billType) {
      try {
        console.log('调用 getNextBillNo，参数:', bill.billType)
        const noRes = await getNextBillNo(bill.billType)
        console.log('单据号生成响应:', noRes)
        // 优先从 data 字段获取，如果没有则从 msg 字段获取（兼容旧版本）
        bill.billNo = noRes?.data || noRes?.msg || ''
        console.log('生成的单据号:', bill.billNo)
        if (!bill.billNo) {
          ElMessage.warning('单据号生成失败，请重试')
        }
      } catch (error) {
        console.error('生成单据号失败:', error)
        ElMessage.error('生成单据号失败：' + (error as any)?.message || '未知错误')
      }
    } else {
      console.warn('未生成单据号，billNo:', bill.billNo, 'billType:', bill.billType)
    }
    return
  }
  // 编辑时：加载数据，但保留正确的 billType
  const res = await getBill(props.id)
  const billData = res?.data || {}
  Object.assign(bill, billData)
  // 确保 billType 使用 props 中的值，防止后端数据错误
  if (props.billType) {
    bill.billType = props.billType
  }
  const lines = await listBillItems(props.id)
  items.splice(0, items.length, ...(lines?.data || []))
}

const onAddLine = () => { items.push({ materialId: '', uomId: '', qty: 0, price: 0, remark: '', uomOptions: [] }) }
const onRemoveLine = (idx: number) => {
  items.splice(idx, 1)
}

const onSave = async (submit: boolean) => {
  loading.value = true
  try {
    // 确保 billType 正确（优先使用 props，如果为空则从路由判断）
    const targetBillType = props.billType || (router.currentRoute.value.path.includes('so-out') ? 'SO_OUT' : 'PO_IN')
    bill.billType = targetBillType
    console.log('保存单据，props.billType:', props.billType, '目标billType:', targetBillType, 'bill.billType:', bill.billType)
    
    // 校验单据头必填字段
    if (!bill.warehouseId || bill.warehouseId === '') {
      ElMessage.error('请选择仓库'); loading.value = false; return
    }
    if (bill.billType === 'PO_IN' && (!bill.partyId || bill.partyId === '')) {
      ElMessage.error('请选择供应商'); loading.value = false; return
    }
    if (bill.billType === 'SO_OUT' && (!bill.partyId || bill.partyId === '')) {
      ElMessage.error('请选择客户'); loading.value = false; return
    }
    // 简单校验：单位与数量
    for (const [idx, row] of items.entries()) {
      if (!row.materialId) { ElMessage.error(`第${idx+1}行未选择物料`); loading.value=false; return }
      if (!row.uomId) { ElMessage.error(`第${idx+1}行未选择计量单位`); loading.value=false; return }
      if (!(Number(row.qty) > 0)) { ElMessage.error(`第${idx+1}行数量必须大于0`); loading.value=false; return }
      if (Number(row.price) < 0) { ElMessage.error(`第${idx+1}行单价不能为负`); loading.value=false; return }
    }
    const itemsPayload = items.map((row:any) => {
      const rate = Number((row.uomOptions||[]).find((u:any)=>String(u.uomId)===String(row.uomId))?.rate || 1)
      const unitEx = rate ? (Number(row.priceBase||0) / rate) : Number(row.priceBase||0)
      const tr = Number(row.taxRate||0)/100
      const unitIncl = tr ? unitEx * (1 + tr) : unitEx
      const qty = Number(row.qty||0)
      const lineAmount = qty * unitEx // 行金额（未税）
      const lineTax = (bill.priceMode === 'TAX_INCLUDED') ? (tr ? (qty * unitEx * tr) : 0) : (qty * unitEx * tr)
      return {
        ...row,
        unitPriceExcl: unitEx,
        unitPriceIncl: unitIncl,
        amount: lineAmount, // 行金额（未税）
        lineTaxAmount: lineTax,
        priceMode: bill.priceMode
      }
    })
    const payload = { bill, items: itemsPayload, submit }
    await saveSubmit(payload as any)
    ElMessage.success(submit ? '保存并提交成功' : '保存成功')
    router.back()
  } finally {
    loading.value = false
  }
}

const onBack = () => router.back()

const remoteMaterial = async (query: string, row?: any) => {
  loadingMaterial.value = true
  try {
    const res = await pageMaterial({ pageNum: 1, pageSize: 20, materialCode: query, materialName: query })
    materialOptions.value = res?.data?.records || []
  } finally {
    loadingMaterial.value = false
  }
}

const remoteWarehouse = async (query: string) => {
  loadingWarehouse.value = true
  try {
    const res = await pageWarehouse({ pageNum: 1, pageSize: 20, warehouseCode: query, warehouseName: query })
    warehouseOptions.value = res?.data?.records || []
  } finally {
    loadingWarehouse.value = false
  }
}

watch(() => items.map(i => i.materialId), async (vals, prev) => {
  // 当物料变更时联动单位选项
  for (let i = 0; i < items.length; i++) {
    const row = items[i]
    if (!row || !row.materialId || row.materialId === '') continue
    const res = await listUomConv(String(row.materialId))
    row.uomOptions = res?.data || []
    if (!row.uomId && row.uomOptions.length > 0) row.uomId = String(row.uomOptions[0].uomId)
    // 默认价与税率（基于物料/价表，当前服务返回物料税率与默认价）
    try {
      const p = await getDefaultPrice({ billType: bill.billType, materialId: String(row.materialId), partyId: bill.partyId ? String(bill.partyId) : undefined, uomId: row.uomId ? String(row.uomId) : undefined })
      const taxRate = Number(p?.data?.taxRate ?? 0) / 100
      const priceRaw = Number(p?.data?.price ?? 0)
      const rate = Number((row.uomOptions||[]).find((u:any)=>String(u.uomId)===String(row.uomId))?.rate || 1)
      // 将默认价统一折算为基准单位的未税基准价 priceBaseExcl
      let unitExcl = p?.data?.taxIncluded === 1 ? (taxRate ? priceRaw / (1 + taxRate) : priceRaw) : priceRaw
      let baseExcl = p?.data?.matchedUom ? (rate ? unitExcl * rate : unitExcl) : unitExcl
      row.priceBase = baseExcl // 基准单位未税价
      row.taxRate = p?.data?.taxRate ?? null
      row.priceMatched = !!p?.data?.matched
      // 按当前模式显示
      if (bill.priceMode === 'TAX_INCLUDED') {
        const unitEx = rate ? (row.priceBase / rate) : row.priceBase
        row.price = taxRate ? unitEx * (1 + taxRate) : unitEx
      } else {
        row.price = rate ? (row.priceBase / rate) : row.priceBase
      }
    } catch {}
  }
})

watch(() => items.map(i => i.uomId), async (vals) => {
  // 当单位变化时：尝试命中单位级价目，否则按基准换算
  for (let i = 0; i < items.length; i++) {
    const row = items[i]
    if (!row || !row.materialId || row.materialId === '' || !row.uomId || row.uomId === '') continue
    const rate = Number((row.uomOptions||[]).find((u:any)=>String(u.uomId)===String(row.uomId))?.rate || 1)
    try {
      const p = await getDefaultPrice({ billType: bill.billType, materialId: String(row.materialId), partyId: bill.partyId ? String(bill.partyId) : undefined, uomId: row.uomId ? String(row.uomId) : undefined })
      const taxRate = Number(p?.data?.taxRate ?? 0) / 100
      const priceRaw = Number(p?.data?.price ?? 0)
      if (p?.data?.matchedUom) {
        const unitExcl = p?.data?.taxIncluded === 1 ? (taxRate ? priceRaw / (1 + taxRate) : priceRaw) : priceRaw
        row.priceBase = rate ? unitExcl * rate : unitExcl
        if (bill.priceMode === 'TAX_INCLUDED') {
          row.price = taxRate ? unitExcl * (1 + taxRate) : unitExcl
        } else {
          row.price = unitExcl
        }
        row.priceMatched = true
      } else {
        if (row.priceBase == null) row.priceBase = rate ? Number(row.price||0) * rate : Number(row.price||0)
        const unitEx = rate ? (row.priceBase / rate) : row.priceBase
        row.price = bill.priceMode === 'TAX_INCLUDED' ? (taxRate ? unitEx * (1 + taxRate) : unitEx) : unitEx
      }
    } catch {
      if (row.priceBase == null) row.priceBase = rate ? Number(row.price||0) * rate : Number(row.price||0)
      const unitEx = rate ? (row.priceBase / rate) : row.priceBase
      const tr = Number(row.taxRate||0)/100
      row.price = bill.priceMode === 'TAX_INCLUDED' ? (tr ? unitEx * (1 + tr) : unitEx) : unitEx
    }
  }
})

watch(() => bill.priceMode, () => {
  // 仅切换显示，基准未税价不变
  for (let i = 0; i < items.length; i++) {
    const row = items[i]
    const rate = Number((row.uomOptions||[]).find((u:any)=>String(u.uomId)===String(row.uomId))?.rate || 1)
    const unitEx = rate ? (Number(row.priceBase||0) / rate) : Number(row.priceBase||0)
    const tr = Number(row.taxRate||0)/100
    row.price = bill.priceMode === 'TAX_INCLUDED' ? (tr ? unitEx * (1 + tr) : unitEx) : unitEx
  }
})

const onViewFlow = async () => {
  ElMessage.info('功能待完成')
  // TODO: 实现查看流程功能
  // if (!bill.billId) { ElMessage.info('尚未保存，暂无流程'); return }
  // const res = await getBillProcId(String(bill.billId))
  // const procId = res?.data
  // if (!procId) { ElMessage.info('暂无流程实例'); return }
  // router.push({ name: 'WorkDetail', params: { procInsId: procId } })
}

onMounted(() => {
  console.log('编辑页面 onMounted，props:', props, '当前路由:', router.currentRoute.value)
  // 再次确保 billType 正确
  if (!props.billType) {
    const routeBillType = router.currentRoute.value.path.includes('so-out') ? 'SO_OUT' : 'PO_IN'
    console.warn('props.billType 为空，从路由判断:', routeBillType)
    bill.billType = routeBillType
  } else {
    bill.billType = props.billType
  }
  console.log('onMounted 后，bill.billType:', bill.billType)
  load()
})

const calcLineTax = (row:any) => {
  const rate = Number((row.uomOptions||[]).find((u:any)=>String(u.uomId)===String(row.uomId))?.rate || 1)
  const unitEx = rate ? (Number(row.priceBase||0) / rate) : Number(row.priceBase||0)
  const tr = Number(row.taxRate||0)/100
  return (bill.priceMode === 'TAX_INCLUDED') ? (tr ? (Number(row.qty||0) * unitEx * tr) : 0) : (Number(row.qty||0) * unitEx * tr)
}

const remoteParty = async (query: string) => {
  loadingParty.value = true
  try {
    if (bill.billType === 'PO_IN') {
      const res = await pageSupplier({ pageNum: 1, pageSize: 20, code: query, name: query })
      partyOptions.value = (res?.data?.records || []).map((s:any)=>({ id: s.supplierId, label: `${s.supplierCode} | ${s.supplierName}` }))
    } else {
      const res = await pageCustomer({ pageNum: 1, pageSize: 20, code: query, name: query })
      partyOptions.value = (res?.data?.records || []).map((c:any)=>({ id: c.customerId, label: `${c.customerCode} | ${c.customerName}` }))
    }
  } finally {
    loadingParty.value = false
  }
}
</script>

<style scoped lang="scss">
.erp-bill-edit {
  &__header { display: flex; align-items: center; justify-content: space-between; }
  &__footer { margin-top: 12px; display: flex; gap: 8px; justify-content: center; }
}
</style>


